package com.ququ.syb.business.payment.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ququ.common.result.Result;
import com.ququ.common.result.ResultJson;
import com.ququ.syb.business.payment.fegin.*;
import com.ququ.syb.business.payment.pojo.PayResult;
import com.ququ.syb.business.payment.pubs.PublicServiceApi;
import com.ququ.syb.business.payment.rabbitmq.RabbitMQSender;
import com.ququ.syb.business.payment.redis.RedisDao;
import com.ququ.syb.common.constant.*;
import com.ququ.syb.common.pojo.PayBankAccountInfo;
import com.ququ.syb.common.pojo.PayChannel;
import com.ququ.syb.common.pojo.PayOrder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class PaymentBusinessService {

    private Logger logger = LoggerFactory.getLogger(PaymentBusinessService.class);

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private BalanceBusinessService balanceBusinessService;
    @Autowired
    private PayOrderFegin payOrderFegin;
    @Autowired
    private AccountFegin accountFegin;
    @Autowired
    private BankCardFegin bankCardFegin;
    @Autowired
    private ChannelsRouterFegin channelsRouterFegin;
    @Autowired
    private PayChannelFegin payChannelFegin;
//    @Autowired
//    private PublicServiceFegin publicServiceFegin;
    @Autowired
    private RedisDao redisDao;
    @Autowired
    private RabbitMQSender rabbitMQSender;
    @Autowired
    private PublicServiceApi publicServiceApi;

    /**
     * 创建订单  p0210接口
     * @param orderno
     * @param amount
     * @param ordertype
     * @param title
     * @param desc
     * @param returnurl
     * @param callbackurl
     * @param withdrawcallbackurl
     * @param payaccountid
     * @param payeeaccountid
     * @param paycommission
     * @param payeecommission
     * @param appcode
     * @param paychannelid
     * @param assureday
     * @param timeout
     * @param divideinfo
     * @return
     */
    public Result<PayOrder> createPayOrder(String orderno, Long amount, Integer ordertype, String title, String desc, String returnurl, String callbackurl,
                                           String withdrawcallbackurl, String payaccountid, String payeeaccountid, Long paycommission, Long payeecommission,
                                           String appcode, String paychannelid, Integer assureday, Integer timeout, String divideinfo){
        return payOrderService.createPayOrder(orderno, amount, ordertype, title, desc, returnurl, callbackurl, withdrawcallbackurl, payaccountid, payeeaccountid, paycommission, payeecommission, appcode, paychannelid, assureday, timeout, divideinfo);
    }


    /**
     * 订单支付 p0211接口
     */
    public Result<PayResult> paymentOrPaySms(String tradenum, String name, String bankcardno, String mobile, String idcardno, String expirydate, String cvv2,
                                             String authcode, String openid, String buyerid, String userip, String extparams){
        Jedis jedis = redisDao.getJedis();
        try {
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            if (payOrder == null)
                return new Result<>(-1, "无此订单号");
            if (payOrder.getStatus() != PayOrderStatusConstant.DEFAULT)
                return new Result<>(-1,"订单已经执行支付，不允许重新支付");
            PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
            if (payChannel == null)
                return new Result<>(-1, "无此通道号或通道不可用");
            PayResult payResult = new PayResult();
            payResult.setTradenum(tradenum);
            payResult.setChanneltype(payChannel.getChanneltype());
            payResult.setPaycommission(payOrder.getPaycommission());
            payResult.setPayeecommission(payOrder.getPayeecommission());
            Map resultMap = null;
            ResultJson payresult = null;
            JSONObject extParams = null;
            boolean directPay = false;
            //处理通道扩展参数
            if (StringUtils.isNotBlank(extparams))
                extParams = JSON.parseObject(extparams);
            else
                extParams = new JSONObject();
            if (StringUtils.isBlank(userip)) {
                try {
                    userip = InetAddress.getLocalHost().getHostAddress();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
            extParams.put("userip", userip);
            if (payOrder.getType() == PayOrderTypeConstant.ASSURE)
                extParams.put("assure",1);
            switch (payChannel.getChanneltype()) {
                case PayChannelTypeConstant.QUICKAPI:
                case PayChannelTypeConstant.QUICKWAP:
                    if (StringUtils.isBlank(bankcardno))
                        return error(-1, "快捷通道必须传入支付卡号",payOrder);
                    PayBankAccountInfo payBankAccountInfo = bankCardFegin.getPayBankAccountInfo(payOrder.getCreateaccount(), bankcardno).getData();
                    if (payBankAccountInfo == null) {
                        //未保存，则必须传入所有参数
                        if (StringUtils.isBlank(name) || StringUtils.isBlank(mobile) || StringUtils.isBlank(idcardno))
                            return error(-1, "快捷通道支付卡参数不全",payOrder);
                        //检查卡数据
                        ResultJson bankCardInfoResult = publicServiceApi.getCardInfo(bankcardno);
                        if (bankCardInfoResult.getStatus() != 1)
                            return error(bankCardInfoResult.getStatus(), bankCardInfoResult.getMsg(),payOrder);
                        Map<String, String> bankCardInfo = (Map<String, String>) bankCardInfoResult.getData();
                        if (Integer.parseInt(bankCardInfo.get("CardType")) == BankCardTypeConstant.CREDIT_CARD && (StringUtils.isBlank(expirydate) || StringUtils.isBlank(cvv2)))
                            return error(-1, "快捷支付信用卡有效期与CVV码参数不全",payOrder);
                        Result<PayBankAccountInfo> payBankAccountInfoResult = bankCardFegin.bindPayBankAccountInfo(payOrder.getCreateaccount(),
                                bankcardno,
                                name,
                                mobile,
                                idcardno);
                        if (payBankAccountInfoResult.getStatus() != 1)
                            return error(payBankAccountInfoResult.getStatus(), payBankAccountInfoResult.getMsg(),payOrder);
                        payBankAccountInfo = payBankAccountInfoResult.getData();
                        if (Integer.parseInt(bankCardInfo.get("CardType")) == BankCardTypeConstant.CREDIT_CARD) {
                            payBankAccountInfoResult = bankCardFegin.savePayBankAccountInfoExpCvv(payOrder.getCreateaccount(),
                                    bankcardno,
                                    expirydate,
                                    cvv2);
                            if (payBankAccountInfoResult.getStatus() != 1)
                                return error(payBankAccountInfoResult.getStatus(), payBankAccountInfoResult.getMsg(),payOrder);
                            payBankAccountInfo = payBankAccountInfoResult.getData();
                        }
                    } else {
                        //已绑定的卡，检查参数
                        if ((StringUtils.isNotBlank(mobile) && !mobile.equals(payBankAccountInfo.getCardholdermobile())) || (StringUtils.isNotBlank(name) && !mobile.equals(payBankAccountInfo.getBankaccountname()))) {
                            //改名或更换手机号了，重绑
                            Result<PayBankAccountInfo> payBankAccountInfoResult = bankCardFegin.bindPayBankAccountInfo(payOrder.getCreateaccount(),
                                    bankcardno,
                                    name,
                                    mobile,
                                    idcardno);
                            if (payBankAccountInfoResult.getStatus() != 1)
                                return error(payBankAccountInfoResult.getStatus(), payBankAccountInfoResult.getMsg(),payOrder);
                            payBankAccountInfo = payBankAccountInfoResult.getData();
                        }
                        if (StringUtils.isNotBlank(expirydate) && StringUtils.isNotBlank(cvv2)) {
                            Result<PayBankAccountInfo> payBankAccountInfoResult = bankCardFegin.savePayBankAccountInfoExpCvv(payOrder.getCreateaccount(),
                                    bankcardno,
                                    expirydate,
                                    cvv2);
                            if (payBankAccountInfoResult.getStatus() != 1)
                                return error(payBankAccountInfoResult.getStatus(), payBankAccountInfoResult.getMsg(),payOrder);
                            payBankAccountInfo = payBankAccountInfoResult.getData();
                        }
                    }
                    payOrder.setBankaccountinfoid(payBankAccountInfo.getId().intValue());
                    if (payChannel.getNeedcvv() != null && payChannel.getNeedcvv() == 1 && (StringUtils.isBlank(payBankAccountInfo.getExpirydate()) || StringUtils.isBlank(payBankAccountInfo.getCvv2())))
                        return error(-1, "快捷通道缺乏信用卡有效期或CVV参数",payOrder);
                    if (payChannel.getExtparam() != null && payChannel.getExtparam().size() > 0) {
                        if (payChannel.getExtparam().contains("bankcode"))
                            extParams.put("bankcode", payBankAccountInfo.getBankcode());
                        if (payChannel.getExtparam().contains("commission"))
                            extParams.put("commission", payOrder.getPayeecommission().toString());
                        for (String param : payChannel.getExtparam()) {
                            if (!extParams.containsKey(param))
                                return error(-1, "缺少扩展参数:" + param,payOrder);
                        }
                        extparams = extParams.toJSONString();
                    }
                    if (payChannel.getChanneltype() == PayChannelTypeConstant.QUICKAPI) {
                        if ((payChannel.getNeedconfirm() != null && payChannel.getNeedconfirm() == 1)
                                || (payChannel.getNeedbind() != null && payChannel.getNeedbind() == 1 && !jedis.exists(payChannel.getBindkey() + payBankAccountInfo.getBankaccountno()))) {
                            //短信支付模式或首次绑卡模式
                            payresult = channelsRouterFegin.quickPayApiSms(payOrder.getPayeeaccount(),
                                    payOrder.getTradenum(),
                                    payOrder.getAmount() + payOrder.getPaycommission(),
                                    payOrder.getTitle(),
                                    payOrder.getDescription(),
                                    payOrder.getPaychannelid(),
                                    payBankAccountInfo.getBankaccountno(),
                                    payBankAccountInfo.getCardholdermobile(),
                                    payBankAccountInfo.getBankaccountname(),
                                    payBankAccountInfo.getCardholderidcard(),
                                    payBankAccountInfo.getExpirydate(),
                                    payBankAccountInfo.getCvv2(),
                                    extparams);
                            if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                                return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                            } else {
                                resultMap = (Map) payresult.getData();
                                payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                            }
                        } else {
                            //直接付款模式
                            directPay=true;
                            payresult = channelsRouterFegin.quickPayApiDirect(payOrder.getPayeeaccount(),
                                    payOrder.getTradenum(),
                                    payOrder.getAmount() + payOrder.getPaycommission(),
                                    payOrder.getTitle(),
                                    payOrder.getDescription(),
                                    payOrder.getPaychannelid(),
                                    payBankAccountInfo.getBankaccountno(),
                                    payBankAccountInfo.getCardholdermobile(),
                                    payBankAccountInfo.getBankaccountname(),
                                    payBankAccountInfo.getCardholderidcard(),
                                    payBankAccountInfo.getExpirydate(),
                                    payBankAccountInfo.getCvv2(),
                                    extparams);
                            if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                                return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                            } else {
                                resultMap = (Map) payresult.getData();
                                payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                                if (payChannel.getNeedquerypay() != null && payChannel.getNeedquerypay() == 1)
                                    rabbitMQSender.send(RabbitMqQueueNameConstant.DEAD_PAYORDER_QUERY_5S,payOrder.getTradenum(),2000L);
                            }
                        }
                    }else{
                        //WAP版快捷
                        payresult = channelsRouterFegin.quickPayWap(payOrder.getPayeeaccount(),
                                payOrder.getTradenum(),
                                payOrder.getAmount() + payOrder.getPaycommission(),
                                payOrder.getTitle(),
                                payOrder.getDescription(),
                                payOrder.getPaychannelid(),
                                payBankAccountInfo.getBankaccountno(),
                                payBankAccountInfo.getCardholdermobile(),
                                payBankAccountInfo.getBankaccountname(),
                                payBankAccountInfo.getCardholderidcard(),
                                payBankAccountInfo.getExpirydate(),
                                payBankAccountInfo.getCvv2(),
                                extparams);
                        if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                            return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                        } else {
                            resultMap = (Map) payresult.getData();
                            payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                        }
                    }
                    break;
                case PayChannelTypeConstant.QRCODE:
                    payresult = channelsRouterFegin.WechatAlipayUpopPay(payOrder.getPayeeaccount(),
                            payOrder.getPaychannelid(),
                            payOrder.getTradenum(),
                            payOrder.getAmount()+payOrder.getPaycommission(),
                            payOrder.getTitle(),
                            userip,
                            null,
                            null,
                            extParams.toJSONString());
                    if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                        return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                    } else {
                        resultMap = (Map) payresult.getData();
                        payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                    }
                    break;
                case PayChannelTypeConstant.SCAN:
                    payresult = channelsRouterFegin.WechatAlipayUpopPay(payOrder.getPayeeaccount(),
                            payOrder.getPaychannelid(),
                            payOrder.getTradenum(),
                            payOrder.getAmount()+payOrder.getPaycommission(),
                            payOrder.getTitle(),
                            userip,
                            authcode,
                            null,
                            extParams.toJSONString());
                    if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                        return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                    } else {
                        resultMap = (Map) payresult.getData();
                        payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                    }
                    rabbitMQSender.send(RabbitMqQueueNameConstant.DEAD_PAYORDER_QUERY_5S,payOrder.getTradenum(),2000L);
                    break;
                case PayChannelTypeConstant.WECHAT_PUBLIC:
                    payresult = channelsRouterFegin.WechatAlipayUpopPay(payOrder.getPayeeaccount(),
                            payOrder.getPaychannelid(),
                            payOrder.getTradenum(),
                            payOrder.getAmount()+payOrder.getPaycommission(),
                            payOrder.getTitle(),
                            userip,
                            null,
                            openid,
                            extParams.toJSONString());
                    if (payresult.getStatus() != ResultStatusConstant.SUCCESS) {
                        return error(payresult.getStatus(), payresult.getMsg(),payOrder);
                    } else {
                        resultMap = (Map) payresult.getData();
                        payResult.setPayurl(resultMap.containsKey("payurl")?resultMap.get("payurl").toString():JSON.toJSONString(resultMap));
                    }
                    break;
                case PayChannelTypeConstant.ALIPAY_SERVICE:

                    break;
                default:
            }
            waitCallback(payOrder,directPay);
            return new Result<>(payResult);
        }catch (Exception e){
            e.printStackTrace();
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            return error(-1,"支付异常:"+e.getMessage(),payOrder);
        }finally {
            redisDao.close(jedis);
        }
    }

    /**
     * 一步支付(p0210+p0211)
     */

    /**
     * 支付短信确认 p0221接口
     */
    public Result<PayResult> quickPaySmsConfirm(String tradenum,String idcode){
        Jedis jedis = redisDao.getJedis();
        try {
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            if (payOrder == null)
                return new Result<>(-1, "无此订单号");
            PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
            if (payChannel == null)
                return error(-1, "无此通道号或通道不可用",payOrder);
            if ((payChannel.getNeedconfirm() == null || payChannel.getNeedconfirm() == 0)&&(payChannel.getNeedbind()==null||payChannel.getNeedbind()==0))
                return error(-1,"本支付通道不支持短信确认",payOrder);
            if (payOrder.getStatus() != PayOrderStatusConstant.TO_BE_CONFIRMED)
                return new Result<>(-1,"订单状态不允许短信确认");
            PayResult payResult = new PayResult();
            payResult.setTradenum(tradenum);
            payResult.setChanneltype(payChannel.getChanneltype());
            payResult.setPaycommission(payOrder.getPaycommission());
            payResult.setPayeecommission(payOrder.getPayeecommission());
            ResultJson confirmResult = channelsRouterFegin.quickPayApiSmsConfirm(payOrder.getPayeeaccount(),
                    payOrder.getTradenum(),
                    payOrder.getPaychannelid(),
                    idcode,
                    null);
            if (confirmResult.getStatus() != ResultStatusConstant.SUCCESS)
                return error(confirmResult.getStatus(),confirmResult.getMsg(),payOrder);
            else {
                waitCallback(payOrder,true);
                if (payChannel.getNeedbind() != null && payChannel.getNeedbind() == 1){
                    PayBankAccountInfo payBankAccountInfo = bankCardFegin.getPayBankAccountInfo(payOrder.getBankaccountinfoid().longValue()).getData();
                    jedis.set(payChannel.getBindkey()+payBankAccountInfo.getBankaccountno(),"1");
                }
                return new Result<>(payResult);
            }
        }catch (Exception e){
            e.printStackTrace();
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            return error(-1,"支付异常:"+e.getMessage(),payOrder);
        }finally {
            redisDao.close(jedis);
        }
    }

    /**
     * 短信重发  p0220接口
     */
    public Result<PayResult> quickPayResendSms(String tradenum){
        try{
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            if (payOrder == null)
                return new Result<>(-1, "无此订单号");
            PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
            if (payChannel == null)
                return error(-1, "无此通道号或通道不可用",payOrder);
            if (payChannel.getAllowresend() == null || payChannel.getAllowresend() == 0)
                return error(-1,"本支付通道不支持短信重发",payOrder);
            if (payOrder.getStatus() != PayOrderStatusConstant.TO_BE_CONFIRMED)
                return new Result<>(-1,"订单状态不允许短信重发");
            ResultJson sendresult = channelsRouterFegin.quickPayApiSmsResend(payOrder.getPayeeaccount(),
                    tradenum,
                    payOrder.getPaychannelid(),
                    null);
            if (sendresult.getStatus() != ResultStatusConstant.SUCCESS)
                return error(sendresult.getStatus(),sendresult.getMsg(),payOrder);
            else {
                return new Result<>();
            }
        }catch (Exception e){
            e.printStackTrace();
            PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
            return error(-1,"短信重发异常:"+e.getMessage(),payOrder);
        }
    }

    /**
     * 支付回调处理
     */
    public void paymentCallback(String tradenum,int status,String failreason){
        switch (status){
            case 1:
                paymentSuccess(tradenum,failreason);
                break;
            case 0:
                paymentFail(tradenum,failreason);
                break;
        }
    }


    /**
     * 支付成功处理
     */
    public void paymentSuccess(String tradenum,String message){
        PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
        PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
        if (payOrder.getStatus() != PayOrderStatusConstant.TO_BE_CONFIRMED){
            logger.debug("支付订单状态不是待支付状态，不允许重复进行成功处理");
            return;
        }
        //修改订单状态
        payOrder.setStatus(payOrder.getType()==PayOrderTypeConstant.ASSURE?PayOrderStatusConstant.PAY_TO_ASSURE_SUCCESS:PayOrderStatusConstant.SUCCESS);
        payOrder.setFailreason(StringUtils.isBlank(message)?"交易成功":message);
        payOrder = payOrderFegin.update(payOrder).getData();
        //余额变动+流水
        if (payOrder.getType() != PayOrderTypeConstant.ASSURE) {
            if (payOrder.getCreateaccount().equals(payOrder.getPayeeaccount())) {
                //代收订单，收付款accountid相同
                balanceBusinessService.payeeReceipt(payOrder);
                balanceBusinessService.payeeDivide(payOrder);
            } else {
                balanceBusinessService.payerRecharge(payOrder);
                balanceBusinessService.payerDeduct(payOrder);
                balanceBusinessService.payeeReceipt(payOrder);
                balanceBusinessService.payeeDivide(payOrder);
            }
        }else {
            balanceBusinessService.payerRecharge(payOrder);
            balanceBusinessService.payerDeduct(payOrder);
            balanceBusinessService.assureReceipt(payOrder);
        }
        //通道收款
        balanceBusinessService.channelAccountReceipt(payOrder,payChannel.getAccountid().toString());
        //应用收款
        balanceBusinessService.applicationAccountReceipt(payOrder);
        //直清或伪直清
        if (payOrder.getType() != PayOrderTypeConstant.ASSURE && payChannel.getIsAutoClear() != PayChannelClearTypeConstant.NO_AUTO_CLEAR)
            rabbitMQSender.send(RabbitMqQueueNameConstant.DIRECT_CLEAR_WITHDRAW_CREATE_ORDER,tradenum);
        //发送应用回调
        rabbitMQSender.send(RabbitMqQueueNameConstant.NOTIFY_PAYORDER,tradenum);
    }

    /**
     * 支付失败处理
     */
    public void paymentFail(String tradenum, String message){
        PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
        PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
        if (payOrder.getStatus() != PayOrderStatusConstant.TO_BE_CONFIRMED){
            logger.debug("支付订单状态不是待支付状态，不允许重复进行支付失败处理");
            return;
        }
        //修改订单状态
        payOrder.setStatus(PayOrderStatusConstant.FAIL);
        payOrder.setFailreason(StringUtils.isBlank(message)?"交易失败":message);
        payOrder = payOrderFegin.update(payOrder).getData();
        //发送应用回调
        rabbitMQSender.send(RabbitMqQueueNameConstant.NOTIFY_PAYORDER,tradenum);
    }


    /**
     * 订单退款处理
     */
    public boolean paymentRefund(String tradenum){
        PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
        PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
        if (!((payOrder.getPaychannelid().startsWith("252") && payOrder.getStatus() != PayOrderStatusConstant.SUCCESS)
                || (payOrder.getType()==PayOrderTypeConstant.ASSURE && payOrder.getStatus() == PayOrderStatusConstant.PAY_TO_ASSURE_SUCCESS))){
            logger.debug("支付订单状态不允许退款或通道不允许退款");
            return false;
        }
        //调用通道退款接口
        JSONObject extParams = new JSONObject();
        extParams.put("commission",payOrder.getPayeecommission());
        ResultJson refundResult = channelsRouterFegin.refund(payOrder.getPayeeaccount(),
                payOrder.getPaychannelid(),
                tradenum,
                payOrder.getAmount()+payOrder.getPaycommission()-payOrder.getPayeecommission(),
                extParams.toJSONString());
        if (refundResult.getStatus() == ResultStatusConstant.SUCCESS) {
            //退款成功
            //修改订单状态
            payOrder.setStatus(PayOrderStatusConstant.ASSURE_REFUND_SUCCESS);
            payOrder.setFailreason("退款成功");
            payOrder = payOrderFegin.update(payOrder).getData();
            //余额变动+流水
            if (payOrder.getType() == PayOrderTypeConstant.ASSURE) {
                balanceBusinessService.assureRefund(payOrder);
            } else {
                balanceBusinessService.payeeRefund(payOrder);
            }
            //通道退款
            balanceBusinessService.channelAccountRefund(payOrder, payChannel.getAccountid().toString());
            //应用退款
            balanceBusinessService.applicationAccountRefund(payOrder);
            return true;
        }else
            return false;
    }


    /**
     * 担保确认处理
     */
    public boolean paymentAssureConfirm(String tradenum){
        PayOrder payOrder = payOrderFegin.getPayOrder(tradenum).getData();
        PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
        if (payOrder.getType()!=PayOrderTypeConstant.ASSURE){
            logger.debug("支付订单{}不是担保订单，不允许担保确认操作",tradenum);
            return false;
        }
        if (payOrder.getStatus() != PayOrderStatusConstant.PAY_TO_ASSURE_SUCCESS){
            logger.debug("支付订单{}状态{}不是预付款成功状态，不允许担保确认操作",tradenum,payOrder.getStatus());
        }
        //调用通道退款接口
        ResultJson assureConfirmResult = channelsRouterFegin.payAssureConfirm(payOrder.getPayeeaccount(),
                payOrder.getPaychannelid(),
                tradenum,
                payOrder.getAmount()+payOrder.getPaycommission()-payOrder.getPayeecommission(),
                payOrder.getDivideinfo());
        if (assureConfirmResult.getStatus() == ResultStatusConstant.SUCCESS) {
            //退款成功
            //修改订单状态
            payOrder.setStatus(PayOrderStatusConstant.SUCCESS);
            payOrder.setFailreason("担保确认成功");
            payOrder = payOrderFegin.update(payOrder).getData();
            //余额变动+流水
            balanceBusinessService.assureDeduct(payOrder);
            balanceBusinessService.payeeReceipt(payOrder);
            balanceBusinessService.payeeDivide(payOrder);
            //通道收款
//            balanceBusinessService.channelAccountReceipt(payOrder, payChannel.getAccountid().toString());
            //应用收款
//            balanceBusinessService.applicationAccountReceipt(payOrder);
            //发送应用回调
            rabbitMQSender.send(RabbitMqQueueNameConstant.NOTIFY_PAYORDER,tradenum);
            //直清或伪直清
            if (payChannel.getIsAutoClear() != PayChannelClearTypeConstant.NO_AUTO_CLEAR)
                rabbitMQSender.send(RabbitMqQueueNameConstant.DIRECT_CLEAR_WITHDRAW_CREATE_ORDER,tradenum);
            return true;
        }else
            return false;
    }


    /**
     * 担保延期处理
     */


    /**
     * 订单超时处理
     */


    /**
     * 错误处理
     */
    private Result<PayResult> error(int status,String msg, PayOrder payOrder){
        if (payOrder.getStatus() == PayOrderStatusConstant.DEFAULT || payOrder.getStatus() == PayOrderStatusConstant.TO_BE_CONFIRMED) {
            payOrder.setStatus(PayOrderStatusConstant.FAIL);
            payOrder.setPaytime(new Date());
            payOrder.setFailreason(msg);
            payOrderFegin.update(payOrder);
        }
        return new Result<>(status,msg);
    }

    /**
     * 订单设置成待回调状态
     * @param payOrder
     */
    private void waitCallback(PayOrder payOrder,boolean directPay){
        if (payOrder.getStatus() == PayOrderStatusConstant.DEFAULT){
            payOrder.setStatus(PayOrderStatusConstant.TO_BE_CONFIRMED);
            payOrder.setPaytime(new Date());
            payOrderFegin.update(payOrder);
        }
        //无支付回调通道特殊处理
        PayChannel payChannel = payChannelFegin.getPayChannel(payOrder.getPaychannelid()).getData();
        if (payChannel.getNopaycallback() != null && payChannel.getNopaycallback() == 1 & directPay){
            Map<String, Object> map = new HashMap<>();
            map.put("tradenum", payOrder.getTradenum());
            map.put("status", 1);
            map.put("failreason", "交易成功");
            rabbitMQSender.send(RabbitMqQueueNameConstant.PAYORDER_CALLBACK, JSON.toJSONString(map));
        }
    }
}
